using System;
using FireStarterModeller.BO;
using FireStarterModeller.Logic;
using FireStarterModeller.UI.Relationship;
using Habanero.Faces.Base;
using Microsoft.Practices.Unity;
using NUnit.Framework;
using Rhino.Mocks;

namespace FireStarterModeller.Test.UI.Relationships
{
    [TestFixture]
    public class TestCreateRelationshipWizardStep1
    {
        [SetUp]
        public void SetupTest()
        {
            //Runs every time that any testmethod is executed
            UITestUtils.SetupTest();
        }

        [TestFixtureSetUp]
        public void TestFixtureSetup()
        {
            //Code that is executed before any test is run in this class. If multiple tests
            // are executed then it will still only be called once.
            UITestUtils.SetupFixture();
        }

        [TearDown]
        public void TearDownTest()
        {
            //runs every time any testmethod is complete
        }

        [Test]
        public void Test_CreateStepWithNullThrowsError()
        {
            //---------------Set up test pack-------------------
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            try
            {
                new CreateRelationshipWizardStep1(null, GlobalUIRegistry.ControlFactory);
                Assert.Fail("expected ArgumentNullException");
            }
                //---------------Test Result -----------------------
            catch (ArgumentNullException ex)
            {
                StringAssert.Contains("Value cannot be null", ex.Message);
                StringAssert.Contains("relationshipCreator", ex.ParamName);
            }
        }

        [Test]
        public void TestStep1_InitialiseStep()
        {
            //---------------Set up test pack-------------------]
            DMClass ownerClass = TestUtilsDMClass.CreateUnsavedValidDMClass();
            DMRelationshipCreator relationshipCreator = new DMRelationshipCreator(ownerClass);
            IWizardStep step1 = new CreateRelationshipWizardStep1(relationshipCreator, GlobalUIRegistry.ControlFactory);
            //---------------Execute Test ----------------------
            step1.InitialiseStep();
            //---------------Test Result -----------------------
            string message;
            Assert.IsFalse(step1.CanMoveOn(out message), "AutoSelects No Blank Item");
        }

        [Test]
        public void TestStep1_MustFillWithAvailableClasses()
        {
            //---------------Set up test pack-------------------]
            DMClass ownerClass = TestUtilsDMClass.CreateUnsavedValidDMClass();
            DMRelationshipCreator relationshipCreator = new DMRelationshipCreator(ownerClass);
            CreateRelationshipWizardStep1 step1 = new CreateRelationshipWizardStep1(relationshipCreator, GlobalUIRegistry.ControlFactory);
            //---------------Execute Test ----------------------
            step1.InitialiseStep();
            //---------------Test Result -----------------------
            IComboBox relatedClassCombo = step1.RelatedClassComboBox;
            Assert.AreEqual(2, relatedClassCombo.Items.Count, "The business object can be related to itself");
        }

//        [Test]
//        public void TestConstruct_WhenSetsRelatedClassComboBox()
//        {
//            //---------------Set up test pack-------------------]
//            DMClass ownerClass = TestUtilsDMClass.CreateSavedDMClass();
//            TestUtilsDMClass.CreateSavedDMClass();
//            //---------------Execute Test ----------------------
//            CreateRelationshipWizardStep1 step1 = new CreateRelationshipWizardStep1(ownerClass, GlobalUIRegistry.ControlFactory);
//            //---------------Test Result -----------------------
//            Assert.IsNotNull(step1.RelatedClassComboBox);
//            IPanelInfo info = step1.PanelInfo;
//            IComboBox relatedClassCombo = step1.RelatedClassComboBox;
//            Assert.AreSame(relatedClassCombo, step1.RelatedClassComboBox);
//        }

        [Test]
        public void TestStep1_WhenTwoClasses_MustFillWithAvailableClasses()
        {
            //---------------Set up test pack-------------------]
            DMClass ownerClass = TestUtilsDMClass.CreateSavedDMClass();
            TestUtilsDMClass.CreateSavedDMClass(ownerClass.Solution);
            DMRelationshipCreator relationshipCreator = new DMRelationshipCreator(ownerClass);
            CreateRelationshipWizardStep1 step1 = new CreateRelationshipWizardStep1(relationshipCreator, GlobalUIRegistry.ControlFactory);
            //---------------Execute Test ----------------------
            step1.InitialiseStep();
            //---------------Test Result -----------------------
            IComboBox relatedClassCombo = step1.RelatedClassComboBox;
            Assert.AreEqual(3, relatedClassCombo.Items.Count, "The business object can be related to itself");
        }

        [Test]
        public void TestCanMoveOn_WhenNoRelatedClass_ShouldBeFalse()
        {
            //---------------Set up test pack-------------------
            DMClass ownerClass = TestUtilsDMClass.CreateSavedDMClass();
            DMRelationshipCreator relationshipCreator = new DMRelationshipCreator(ownerClass);
            CreateRelationshipWizardStep1 step1 = new CreateRelationshipWizardStep1(relationshipCreator, GlobalUIRegistry.ControlFactory);

            step1.InitialiseStep();
            step1.RelatedClassComboBox.SelectedItem = null;

            //---------------Execute Test ----------------------
            string message;
            bool canMoveOn = step1.CanMoveOn(out message);
            //---------------Test Result -----------------------
            Assert.IsFalse(canMoveOn);
            StringAssert.Contains("You must select a related class", message);
            //---------------Tear Down -------------------------
        }

        [Test]
        public void TestCanMoveOn_WhenNoRelatedClass_SelectedItemEmptyString_ShouldBeFalse()
        {
            //---------------Set up test pack-------------------
            DMClass ownerClass = TestUtilsDMClass.CreateSavedDMClass();
            DMRelationshipCreator relationshipCreator = new DMRelationshipCreator(ownerClass);
            CreateRelationshipWizardStep1 step1 = new CreateRelationshipWizardStep1(relationshipCreator, GlobalUIRegistry.ControlFactory);

            step1.InitialiseStep();
            step1.RelatedClassComboBox.SelectedItem = String.Empty;

            //---------------Execute Test ----------------------
            string message;
            bool canMoveOn = step1.CanMoveOn(out message);
            //---------------Test Result -----------------------
            Assert.IsFalse(canMoveOn);
            StringAssert.Contains("You must select a related class", message);
        }

        [Test]
        public void Test_CanMove_WhenRelatedClass_ShouldBeTrue()
        {
            //---------------Set up test pack-------------------
            DMClass ownerClass = TestUtilsDMClass.CreateSavedDMClass();
            DMClass relatedClass = TestUtilsDMClass.CreateSavedDMClass(ownerClass.Solution);
            DMRelationshipCreator relationshipCreator = new DMRelationshipCreator(ownerClass);
            CreateRelationshipWizardStep1 step1 = new CreateRelationshipWizardStep1(relationshipCreator, GlobalUIRegistry.ControlFactory);

            step1.InitialiseStep();
            step1.RelatedClassComboBox.SelectedItem = relatedClass;

            //---------------Execute Test ----------------------
            string message;
            bool canMoveOn = step1.CanMoveOn(out message);
            //---------------Test Result -----------------------
            Assert.IsTrue(canMoveOn);
            Assert.AreEqual("", message);
        }

        [Test]
        public void Test_CanMove_WhenRelatedClass_ShouldSetRelationshipCreatorsRelatedClass()
        {
            //---------------Set up test pack-------------------
            DMClass ownerClass = TestUtilsDMClass.CreateSavedDMClass();
            DMClass relatedClass = TestUtilsDMClass.CreateSavedDMClass(ownerClass.Solution);
            DMRelationshipCreator relationshipCreator = new DMRelationshipCreator(ownerClass);
            CreateRelationshipWizardStep1 step1 = new CreateRelationshipWizardStep1(relationshipCreator, GlobalUIRegistry.ControlFactory);

            step1.InitialiseStep();
            step1.RelatedClassComboBox.SelectedItem = relatedClass;
            //---------------Execute Test ----------------------
            string message;
            bool canMoveOn = step1.CanMoveOn(out message);
            //---------------Test Result -----------------------
            Assert.IsTrue(canMoveOn);
            Assert.AreEqual("", message);
            Assert.AreSame(relatedClass, relationshipCreator.Relationship.RelatedClass);
        }

        [Test]
        public void Test_MoveOn_WhenCanFindForeignKey_ShouldCallSetupRelationship()
        {
            //---------------Set up test pack-------------------
            //---------------Set up test pack-------------------
            IUnityContainer container = new UnityContainer();
            DMClass dmClass = TestUtilsDMClass.CreateSavedDMClass();
            var relationshipCreator = MockRepository.GenerateMock<DMRelationshipCreator>(dmClass);
            container.RegisterInstance(relationshipCreator);

            CreateRelationshipWizardStep1 step1 = new CreateRelationshipWizardStep1(relationshipCreator, GlobalUIRegistry.ControlFactory);
            step1.InitialiseStep();
            relationshipCreator.Stub(creator => creator.CanFindForeignKey).Return(true);
            //---------------Assert Precondition----------------
            Assert.IsTrue(relationshipCreator.CanFindForeignKey);
            relationshipCreator.AssertWasNotCalled(dmRelationshipCreator => dmRelationshipCreator.SetupRelationship());
            //---------------Execute Test ----------------------
            step1.MoveOn();
            //---------------Test Result -----------------------
            relationshipCreator.AssertWasCalled(dmRelationshipCreator => dmRelationshipCreator.SetupRelationship());
        }

        [Test]
        public void Test_MoveOn_WhenNotCanFindForeignKey_ShouldNotCallSetupRelationship()
        {
            //---------------Set up test pack-------------------
            //---------------Set up test pack-------------------
            IUnityContainer container = new UnityContainer();
            DMClass dmClass = TestUtilsDMClass.CreateSavedDMClass();
            var relationshipCreator = MockRepository.GenerateMock<DMRelationshipCreator>(dmClass);
            container.RegisterInstance(relationshipCreator);

            CreateRelationshipWizardStep1 step1 = new CreateRelationshipWizardStep1(relationshipCreator, GlobalUIRegistry.ControlFactory);
            step1.InitialiseStep();
            relationshipCreator.Stub(creator => creator.CanFindForeignKey).Return(false);
            //---------------Assert Precondition----------------
            Assert.IsFalse(relationshipCreator.CanFindForeignKey);
            relationshipCreator.AssertWasNotCalled(dmRelationshipCreator => dmRelationshipCreator.SetupRelationship());
            //---------------Execute Test ----------------------
            step1.MoveOn();
            //---------------Test Result -----------------------
            relationshipCreator.AssertWasNotCalled(dmRelationshipCreator => dmRelationshipCreator.SetupRelationship());
        }

        [Test]
        public void Test_UndoMoveOn_WhenCanFindForeignKey_ShouldCallCancelCreatedProps()
        {
            //---------------Set up test pack-------------------
            IUnityContainer container = new UnityContainer();
            DMClass dmClass = TestUtilsDMClass.CreateSavedDMClass();
            var relationshipCreator = MockRepository.GenerateMock<DMRelationshipCreator>(dmClass);
            container.RegisterInstance(relationshipCreator);

            CreateRelationshipWizardStep1 step1 = new CreateRelationshipWizardStep1(relationshipCreator, GlobalUIRegistry.ControlFactory);
            step1.InitialiseStep();
            relationshipCreator.Stub(creator => creator.CanFindForeignKey).Return(true);
            //---------------Assert Precondition----------------
            Assert.IsTrue(relationshipCreator.CanFindForeignKey);
            relationshipCreator.AssertWasNotCalled(dmRelationshipCreator => dmRelationshipCreator.CancelCreatedProperties());
            //---------------Execute Test ----------------------
            step1.UndoMoveOn();
            //---------------Test Result -----------------------
            relationshipCreator.AssertWasCalled(dmRelationshipCreator => dmRelationshipCreator.CancelCreatedProperties());
        }

        [Test]
        public void Test_UndoMoveOn_WhenNotCanFindForeignKey_ShouldCallCancelCreatedProps()
        {
            //---------------Set up test pack-------------------
            IUnityContainer container = new UnityContainer();
            DMClass dmClass = TestUtilsDMClass.CreateSavedDMClass();
            var relationshipCreator = MockRepository.GenerateMock<DMRelationshipCreator>(dmClass);
            container.RegisterInstance(relationshipCreator);

            CreateRelationshipWizardStep1 step1 = new CreateRelationshipWizardStep1(relationshipCreator, GlobalUIRegistry.ControlFactory);
            step1.InitialiseStep();
            relationshipCreator.Stub(creator => creator.CanFindForeignKey).Return(false);
            //---------------Assert Precondition----------------
            Assert.IsFalse(relationshipCreator.CanFindForeignKey);
            relationshipCreator.AssertWasNotCalled(dmRelationshipCreator => dmRelationshipCreator.CancelCreatedProperties());
            //---------------Execute Test ----------------------
            step1.UndoMoveOn();
            //---------------Test Result -----------------------
            relationshipCreator.AssertWasCalled(dmRelationshipCreator => dmRelationshipCreator.CancelCreatedProperties());
        }
    }
}